import { useEffect, useRef } from 'react';
import { ComponentProps } from 'react';

import TableFrame from '@/components/TableFrame';
import TableSearch, { TableSearchRef } from '@/components/TableSearch';

import useSetState from './useSetState';

type TableFrameProps = ComponentProps<typeof TableFrame>;
export default function useTable<T>({
  columns,
  request,
  deps = [],
  search,
}: {
  columns: TableFrameProps['columns'];
  request: (opts: {
    pageSize: number;
    pageNum: number;
    [key: string]: any;
  }) => Promise<{ list: T[]; pageNum: number; pageSize: number; total: number }>;
  deps?: any[];
  search?: ComponentProps<typeof TableSearch>;
}) {
  const [{ list, total, loading, key }, setState] = useSetState({
    list: [] as T[],
    total: 0,
    loading: false,
    key: 0,
  });
  const [params, setParams] = useSetState({ pageNum: 1, pageSize: 20 });
  function getParams() {
    return Object.assign({}, params, form.current?.getFieldsValue());
  }
  const form = useRef<TableSearchRef>();
  const run = async () => {
    setState({ loading: true });
    try {
      const { pageNum, pageSize, ...obj } = await request(getParams());

      setState(obj);
      setParams({ pageNum, pageSize });
    } catch (error) {
      /* empty */
    }
    setState({ loading: false });
  };
  if (search) {
    search.onReset =
      search.onReset ||
      function () {
        if (form.current) {
          form.current.resetFields();
        }
        run();
      };
    search.onSearch =
      search.onSearch ||
      function () {
        run();
      };
  }

  useEffect(() => {
    run();
  }, [key, ...deps]);

  return {
    context: (
      <TableFrame
        tableLayout="fixed"
        loading={loading}
        pagination={{
          size: 'default',
          current: params.pageNum,
          pageSize: params.pageSize,
          total: total,
          showSizeChanger: true,
          onChange: (pageNum, pageSize) => {
            setState({ key: key + 1 });
            setParams({ pageNum, pageSize });
          },
        }}
        dataSource={list}
        columns={columns}
        search={search ? <TableSearch ref={form} {...search} /> : undefined}
      />
    ),
    run,
    getParams,
    list,
  };
}
